package com.gcxy.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gcxy.constant.PermissionConst;
import com.gcxy.config.listener.UserImportListener;
import com.gcxy.constant.StringConst;
import com.gcxy.core.PageVO;
import com.gcxy.core.R;
import com.gcxy.core.file.AddUserTemplate;
import com.gcxy.dto.*;

import com.gcxy.dto.clazz.ClazzInfoDTO;
import com.gcxy.dto.position.PositionInfoDTO;
import com.gcxy.dto.student.AddStudentInfoDTO;
import com.gcxy.dto.student.DeleteStudentDTO;
import com.gcxy.dto.student.StudentPageDTO;
import com.gcxy.dto.student.UpdateStudentDTO;
import com.gcxy.entity.*;
import com.gcxy.enums.ResultCodeEnum;
import com.gcxy.mapper.*;
import com.gcxy.service.*;
import com.gcxy.utils.BeanCopyUtil;
import com.gcxy.utils.CollectionUtil;
import com.gcxy.utils.ExcelUtil;
import com.gcxy.vo.agency.AgencyVO;
import com.gcxy.vo.resource.ResourceVO;
import com.gcxy.vo.role.RoleVO;
import com.gcxy.vo.student.StudentPageVO;
import com.gcxy.vo.student.StudentTeacherVO;
import com.gcxy.vo.user.UserPureVO;
import com.gcxy.vo.user.UserVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * Copyright (C), 2024-2024, BUG闭退！
 * Author: Huang先森
 * Date: 2024/8/2 10:21
 * FileName: StudentServiceImpl
 * Description:
 */
@Service
public class StudentServiceImpl extends ServiceImpl<UserMapper, User> implements StudentService {

    @Resource
    private UserService userService;

    @Resource
    private PasswordEncoder passwordEncoder;

    @Resource
    private AgencyService agencyService;

    @Resource
    private ClazzService clazzService;

    @Resource
    private PositionService positionService;

    @Resource
    private StudentTeacherService studentTeacherService;
    @Autowired
    private UserMapper userMapper;

    @Autowired
    private PositionMapper positionMapper;

    @Autowired
    private ClazzMapper clazzMapper;

    @Autowired
    private StudentTeacherMapper studentTeacherMapper;

    @Resource
    private SemesterService semesterService;

    @Resource
    private UserRoleService userRoleService;

    @Resource
    private ProjectService projectService;

    @Resource
    private UserProjectService userProjectService;
    @Autowired
    private ProjectMapper projectMapper;
    @Autowired
    private UserProjectMapper userProjectMapper;

    /**
     * 下载批量新增用户模板
     *
     * @param response
     * @return
     */
    @Override
    public R<?> downloadAddUserTemple(HttpServletResponse response) {
        String fileName = "批量添加用户模板";
        String sheetName = "用户信息";

        List<AddUserTemplate> listDate = new ArrayList<>();
        AddUserTemplate addStudentTemplate = new AddUserTemplate();
        addStudentTemplate.setStudentAccount("2090005**");
        addStudentTemplate.setStudentName("袁**");
        addStudentTemplate.setPostName("后端开发工程师");
        addStudentTemplate.setClassInfo("22软工1班");
        addStudentTemplate.setProjectList("项目1" + StringConst.PROJECT_SEPARATOR + "项目2");
        addStudentTemplate.setTeacherAccount("05***");
        addStudentTemplate.setTeacherName("张三");
        addStudentTemplate.setNominalTeacherAccount("06***");
        addStudentTemplate.setNominalTeacherName("李四");

        List<Integer> excludeColumnNames = new ArrayList<>();
        List<ResourceVO> resourceVOList = userService.getUserInfo().getUserResource();
        boolean hasShowTrueTeacher = resourceVOList.stream()
                .anyMatch(resourceVO -> resourceVO.getResourcePath().equals(PermissionConst.SOFTWARE_RESEARCH_INSTITUTE_AGENCY_ADMIN));
        if (!hasShowTrueTeacher) {
            excludeColumnNames.add(7);
            excludeColumnNames.add(8);
        }

        listDate.add(addStudentTemplate);
        try {
            ExcelUtil.writeExcel(response, fileName, sheetName, AddUserTemplate.class, listDate, excludeColumnNames);
        } catch (Exception e) {
            return R.Failed(ResultCodeEnum.BUSINESS_ERROR.getCode(), ResultCodeEnum.BUSINESS_ERROR.getMessage());
        }
        return R.Success();
    }




    /**
     * 新增学生
     *
     * @param addStudentInfoDTO
     * @return
     */
    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public R<?> insertStudent(AddStudentInfoDTO addStudentInfoDTO) {
        if (addStudentInfoDTO.getAgencyId() == null) {
            return R.Failed("没有获取到用户组织信息");
        }
        //查询用户账号和名称是否已经存在
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<User>()
                .eq(User::getUsername, addStudentInfoDTO.getStudentAccount());
        User selectUser = getOne(queryWrapper);
        if (!ObjectUtils.isEmpty(selectUser)) {
            selectUser.setUsername(addStudentInfoDTO.getStudentAccount());
            selectUser.setFullName(addStudentInfoDTO.getStudentName());
            selectUser.setAgencyId(addStudentInfoDTO.getAgencyId());
            // 班级不存在则新建
            Clazz clazz = clazzService.getClazzInfoByName(addStudentInfoDTO.getClassName());
            if (ObjectUtils.isEmpty(clazz)) {
                ClazzInfoDTO clazzInfoDTO = new ClazzInfoDTO();
                clazzInfoDTO.setClassName(addStudentInfoDTO.getClassName());
                Integer row = clazzService.insertClazzInfo(clazzInfoDTO);
                if (row < 0) {
                    return R.Failed("新建学生失败，无法创建班级！");
                }
                selectUser.setClassId(clazzService.getClazzInfoByName(addStudentInfoDTO.getClassName()).getId());
            } else {
                selectUser.setClassId(clazz.getId());
            }
            // 岗位表
            if (addStudentInfoDTO.getPositionName().isEmpty()) {
                return R.Failed("岗位信息不能为空");
            }
            // 岗位表存在则新建
            Position position = positionService.getPositionInfoByName(addStudentInfoDTO.getPositionName());
            if (ObjectUtils.isEmpty(position)) {
                PositionInfoDTO positionInfoDTO = new PositionInfoDTO();
                positionInfoDTO.setName(addStudentInfoDTO.getPositionName());
                Integer row = positionService.insertPosition(positionInfoDTO);
                if (row < 0) {
                    return R.Failed("新建学生信息失败，无法创建岗位信息");
                }
                selectUser.setPositionId(positionService.getPositionInfoByName(addStudentInfoDTO.getPositionName()).getId());
            } else {
                selectUser.setPositionId(position.getId());
            }
            boolean save = updateById(selectUser);
            if (!save) {
                return R.Failed("新增学生信息失败！");
            }

            // 绑定角色信息
            List<RoleVO> roleVOList = userRoleService.getRoleByUserId(selectUser.getId());
            //判断当前用户是否拥有改角色
            if (!roleVOList.stream().anyMatch(roleVO -> roleVO.getId().equals(StringConst.STUDENT))) {
                boolean resultRole = userRoleService.insertUserRole(selectUser.getId(), StringConst.STUDENT);
                if (!resultRole) {
                    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                    return R.Failed("新增学生信息失败，无法绑定角色信息");
                }
            }

            // 绑定项目  使用saveOrUpdate
            projectService.insertProject(addStudentInfoDTO.getProjectList());

            // 绑定项目  使用saveOrUpdate
            projectService.insertProject(addStudentInfoDTO.getProjectList());
            //绑定
            userProjectService.insertStudentProject(addStudentInfoDTO.getProjectList(), selectUser.getId(), addStudentInfoDTO.getSemesterId());
            // 绑定教师
            if (null != addStudentInfoDTO.getHonoraryTeacherId()) {
                boolean result = studentTeacherService.insertStudentTeacher(addStudentInfoDTO, selectUser);
                if (!result) {
                    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                    return R.Failed("新增学生信息失败，请查看教师和学期信息");
                }
            }
            return R.Success("新增学生信息成功！");
        }

        User user = new User();
        user.setUsername(addStudentInfoDTO.getStudentAccount());
        user.setFullName(addStudentInfoDTO.getStudentName());
        user.setEnabled(true);
        user.setAgencyId(addStudentInfoDTO.getAgencyId());
        user.setPassword(passwordEncoder.encode(StringConst.DEFAULT_PASSWORD));

        //  班级
        if (addStudentInfoDTO.getClassName().isEmpty()) {
            return R.Failed("班级信息不能为空");
        }
        // 班级不存在则新建
        Clazz clazz = clazzService.getClazzInfoByName(addStudentInfoDTO.getClassName());
        if (ObjectUtils.isEmpty(clazz)) {
            ClazzInfoDTO clazzInfoDTO = new ClazzInfoDTO();
            clazzInfoDTO.setClassName(addStudentInfoDTO.getClassName());
            Integer row = clazzService.insertClazzInfo(clazzInfoDTO);
            if (row < 0) {
                return R.Failed("新建学生失败，无法创建班级！");
            }
            user.setClassId(clazzService.getClazzInfoByName(addStudentInfoDTO.getClassName()).getId());
        } else {
            user.setClassId(clazz.getId());
        }
        // 岗位表
        if (addStudentInfoDTO.getPositionName().isEmpty()) {
            return R.Failed("岗位信息不能为空");
        }
        // 岗位表存在则新建
        Position position = positionService.getPositionInfoByName(addStudentInfoDTO.getPositionName());
        if (ObjectUtils.isEmpty(position)) {
            PositionInfoDTO positionInfoDTO = new PositionInfoDTO();
            positionInfoDTO.setName(addStudentInfoDTO.getPositionName());
            Integer row = positionService.insertPosition(positionInfoDTO);
            if (row < 0) {
                return R.Failed("新建学生信息失败，无法创建岗位信息");
            }
            user.setPositionId(positionService.getPositionInfoByName(addStudentInfoDTO.getPositionName()).getId());
        } else {
            user.setPositionId(position.getId());
        }
        boolean save = save(user);
        if (!save) {
            return R.Failed("新增学生信息失败！");
        }
        // 绑定角色信息
        boolean resultRole = userRoleService.insertUserRole(user.getId(), StringConst.STUDENT);
        if (!resultRole) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return R.Failed("新增学生信息失败，无法绑定角色信息");
        }
        // 绑定项目  使用saveOrUpdate
        projectService.insertProject(addStudentInfoDTO.getProjectList());
        //绑定
        userProjectService.insertStudentProject(addStudentInfoDTO.getProjectList(), user.getId(), addStudentInfoDTO.getSemesterId());
        // 绑定教师
        if (null != addStudentInfoDTO.getHonoraryTeacherId()) {
            boolean result = studentTeacherService.insertStudentTeacher(addStudentInfoDTO, user);
            if (!result) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return R.Failed("新增学生信息失败，请查看教师和学期信息");
            }
        }
        return R.Success("新增学生信息成功！");
    }


    /**
     * 更新学生
     *
     * @param updateStudentDTO
     * @return
     */
    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public R<?> updateStudent(UpdateStudentDTO updateStudentDTO) {
        //查询用户账号和名称是否已经存在
        User user1 = getById(updateStudentDTO.getId());
        if (ObjectUtils.isEmpty(user1)) {
            return R.Failed("用户名称或者账号不在");
        }
        User user = new User();
        user.setId(updateStudentDTO.getId());
        user.setUsername(updateStudentDTO.getStudentAccount());
        user.setFullName(updateStudentDTO.getStudentName());
        user.setAgencyId(user1.getAgencyId());

        //  班级
        if (updateStudentDTO.getClassName().isEmpty()) {
            return R.Failed("班级信息不能为空");
        }
        // 班级不存在则新建
        Clazz clazz = clazzService.getClazzInfoByName(updateStudentDTO.getClassName());
        if (ObjectUtils.isEmpty(clazz)) {
            ClazzInfoDTO clazzInfoDTO = new ClazzInfoDTO();
            clazzInfoDTO.setClassName(updateStudentDTO.getClassName());
            Integer row = clazzService.insertClazzInfo(clazzInfoDTO);
            if (row < 0) {
                return R.Failed("新建学生失败，无法创建班级！");
            }
            user.setId(clazzService.getClazzInfoByName(updateStudentDTO.getClassName()).getId());
        } else {
            user.setClassId(clazz.getId());
        }
        // 岗位表
        if (updateStudentDTO.getPositionName().isEmpty()) {
            return R.Failed("岗位信息不能为空");
        }
        // 岗位表存在则新建
        Position position = positionService.getPositionInfoByName(updateStudentDTO.getPositionName());
        if (ObjectUtils.isEmpty(position)) {
            PositionInfoDTO positionInfoDTO = new PositionInfoDTO();
            positionInfoDTO.setName(updateStudentDTO.getPositionName());
            Integer row = positionService.insertPosition(positionInfoDTO);
            if (row < 0) {
                return R.Failed("新建学生信息失败，无法创建岗位信息");
            }
            user.setPositionId(positionService.getPositionInfoByName(updateStudentDTO.getPositionName()).getId());
        } else {
            user.setPositionId(position.getId());
        }
        boolean update = updateById(user);
        if (!update) {
            return R.Failed("更新失败！");
        }
        // 删除当前学期下面所有的项目、学生、学期的对应关系

        LambdaQueryWrapper<UserProject> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserProject::getUserId, updateStudentDTO.getId())
                .eq(UserProject::getSemesterId, updateStudentDTO.getSemesterId());

        userProjectService.remove(wrapper);
        projectService.insertProject(updateStudentDTO.getProjectList());

        //绑定
        userProjectService.insertStudentProject(updateStudentDTO.getProjectList(), user.getId(), updateStudentDTO.getSemesterId());

        // 绑定教师
        if (null != updateStudentDTO.getHonoraryTeacherId()) {
            Semester semester = semesterService.getCurrentSemester();
            StudentTeacher studentTeacher = studentTeacherService.getByStudentId(updateStudentDTO.getId(), semester.getId());
            if (ObjectUtils.isEmpty(studentTeacher)) {
                boolean result = studentTeacherService.insertStudentTeacher(updateStudentDTO, user);
                if (!result) {
                    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                    return R.Failed("更新学生信息失败，请查看教师和学期信息");
                }
                return R.Success("更新成功！");
            }

            studentTeacher.setStudentId(updateStudentDTO.getId());
            studentTeacher.setHonoraryTeacherId(updateStudentDTO.getHonoraryTeacherId());
            studentTeacher.setPracticalTeacherId(updateStudentDTO.getPracticalTeacherId());

            boolean result = studentTeacherService.updateStudentTeacher(studentTeacher);
            if (!result) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return R.Failed("更新学生信息失败，请查看教师和学期信息");
            }
        }
        return R.Success("更新成功");
    }

    /**
     * 删除学生
     *
     * @param deleteStudentDTO
     * @return
     */
    @Override
    public R<?> deleteStudent(DeleteStudentDTO deleteStudentDTO) {

        User user = getById(deleteStudentDTO.getId());
        if (ObjectUtils.isEmpty(user)) {
            return R.Failed("删除失败！删除用户不存在！");
        }
        // TODO 修改逻辑 只删除关联关系
        // 删除用户表
//        boolean removeStudent = removeById(id);
//        if (!removeStudent){
//            return R.Failed("删除失败！");
//        }
        //删除关联表
        boolean result = studentTeacherService.removeById(deleteStudentDTO.getStudentTeacherId());
//        boolean result = studentTeacherService.deleteByStudentId(id, semesterService.getCurrentSemester().getId());
        if (!result) {
            return R.Failed("删除失败");
        }
        return R.Success("删除成功！");
    }

    /**
     * 根据分页条件查询获取学生信息
     *
     * @param studentPageDTO
     * @return
     */
    @Override
    public R<PageVO<StudentPageVO>> getStudentPageByCondition(StudentPageDTO studentPageDTO) {
        // 如果不存在semesterId则获取当前学期的id进行查询
        if (null == studentPageDTO.getSemesterId()) {
            Semester semester = semesterService.getCurrentSemester();
            if (ObjectUtils.isEmpty(semester)) {
                return R.Failed("当前学期不存在！");
            }
            studentPageDTO.setSemesterId(semester.getId());
        }

        Page<StudentPageVO> studentPageByCondition = userMapper.getStudentTeacherPageByCondition(new Page<>((Integer) studentPageDTO.getPageNo(), (Integer) studentPageDTO.getPageSize()), studentPageDTO);

        //查询userProject表中user_id 为studentIdList、semester_id为studentPageDTO.getSemesterId的记录
        LambdaQueryWrapper<UserProject> wrapper = new LambdaQueryWrapper<>();
        for (StudentPageVO studentTeacher : studentPageByCondition.getRecords()) {
            wrapper.eq(UserProject::getUserId, studentTeacher.getId())
                    .eq(UserProject::getSemesterId, studentPageDTO.getSemesterId());
            List<UserProject> userProjects = userProjectService.list(wrapper);
            List<String> projectList = userProjects.stream()
                    .map(userProject -> projectService.getById(userProject.getProjectId()).getProjectName())
                    .collect(Collectors.toList());
            studentTeacher.setProjectList(projectList);
            wrapper.clear();
        }

        PageVO studentPageVO = BeanCopyUtil.copy(studentPageByCondition, PageVO.class);
        return R.Success(studentPageVO);
    }

    /**
     * 批量导入学生信息
     *
     * @param batchImportDTO
     * @param response
     * @return
     */
    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public R<?> batchImportStudents(BatchImportDTO batchImportDTO, HttpServletRequest request, HttpServletResponse response) throws IOException {
        //根据agencyId验证权限
        boolean hasPerssion = checkOtherAgencyPerssion(batchImportDTO.getAgencyId(),request);
        if (!hasPerssion) {
            return R.Failed(ResultCodeEnum.INSUFFICIENT_PERMISSIONS.getCode(),ResultCodeEnum.INSUFFICIENT_PERMISSIONS.getMessage());
        }
        Integer semesterId = batchImportDTO.getSemesterId();
        // 检查学期ID
        if (ObjectUtils.isEmpty(semesterId)) {
            return R.Failed("学期ID不能为空！");
        }
        Integer agencyId = batchImportDTO.getAgencyId();
        if (ObjectUtils.isEmpty(agencyId)) {
            return R.Failed("组织机构ID不能为空！");
        }
        // 检查文件
        R result = ExcelUtil.check(batchImportDTO.getFile());
        if (result.failed()) {
            return R.Failed(result.getCode(), result.getMsg());
        }
        //查询当前组织机构的所有用户
        List<UserPureVO> userList = userMapper.getUserListBySemesterIdAndAgencyId(null, null);
        //查询所有学生老师关系表
        List<StudentTeacher> studentTeachers = studentTeacherMapper.selectList(null);
        List<StudentTeacherVO> studentTeacherVOS = BeanCopyUtil.copyList(studentTeachers, StudentTeacherVO.class);
        //创建监听器,监听器中验证数据有效性
        UserImportListener userImportListener = new UserImportListener(response, userList, studentTeacherVOS, batchImportDTO.getAgencyId());
        //解析分件内容
        // 读取Excel文件内容并转换为指定实体类的List列表
        List<AddUserTemplate> addUserTemplateList = EasyExcel.read(batchImportDTO.getFile().getInputStream(),
                        AddUserTemplate.class,
                        userImportListener)
                .sheet()
                .doReadSync();
        //批量插入addUserTemplateList数据
        if (!userImportListener.errorFlag) {
            if (CollectionUtils.isNotEmpty(userImportListener.successList)) {
                return batchImportExcelData(addUserTemplateList, semesterId, agencyId);
            }
        }
        return R.Success();
    }

    private boolean checkOtherAgencyPerssion(Integer agencyId, HttpServletRequest request) {
        UserVO userInfo = userService.getUserInfo();
        //获取用户机构
        AgencyVO agency = userInfo.getAgency();
        Integer userAgencyId = null;
        //获取本人机构id
        if (!ObjectUtils.isEmpty(agency)) {
            userAgencyId = agency.getId();
        }
        // 获取用户资源
        List<ResourceVO> userResource = userInfo.getUserResource();
        boolean flag = false;
        if (CollectionUtils.isNotEmpty(userResource)) {
            String otherPath = PermissionConst.OPERATING_OTHER+request.getRequestURI();
            flag = userResource.stream().anyMatch(ur ->Objects.equals(ur.getResourcePath(),otherPath));
        }
        if (ObjectUtil.equals(agencyId,userAgencyId) || flag) {
            return true;
        }
        return false;
    }

    /**
     * 根据组织id获取当前组织下的学生
     *
     * @param agencyId
     * @return
     */
    @Override
    public List<User> getStudentListByAgencyId(Integer agencyId) {
        List<Integer> studentIds = userRoleService.getAllUserByRoleId(StringConst.STUDENT);
        if (CollectionUtils.isEmpty(studentIds)) {
            return new ArrayList<>();
        }
        //根据组织id获取学生列表
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(User::getId, studentIds)
                .eq(User::getAgencyId, agencyId);
        return list(queryWrapper);
    }

    @Override
    public R<List<StudentPageVO>> getStudentListByCondition(StudentPageDTO studentPageDTO) {
        // 如果不存在semesterId则获取当前学期的id进行查询
        if (null == studentPageDTO.getSemesterId()) {
            Semester semester = semesterService.getCurrentSemester();
            if (ObjectUtils.isEmpty(semester)) {
                return R.Failed("当前学期不存在！");
            }
            studentPageDTO.setSemesterId(semester.getId());
        }

        List<StudentPageVO> studentListByCondition = userMapper.getStudentListPageByCondition(studentPageDTO);

        //查询userProject表中user_id 为studentIdList、semester_id为studentPageDTO.getSemesterId的记录
        LambdaQueryWrapper<UserProject> wrapper = new LambdaQueryWrapper<>();
        for (StudentPageVO studentTeacher : studentListByCondition) {
            wrapper.eq(UserProject::getUserId, studentTeacher.getId())
                    .eq(UserProject::getSemesterId, studentPageDTO.getSemesterId());
            List<UserProject> userProjects = userProjectService.list(wrapper);
            List<String> projectList = userProjects.stream()
                    .map(userProject -> projectService.getById(userProject.getProjectId()).getProjectName())
                    .collect(Collectors.toList());
            studentTeacher.setProjectList(projectList);
            wrapper.clear();
        }

        return R.Success(studentListByCondition);
    }

    /**
     * 批量导入学生信息
     *
     * @param addUserTemplateList 用户信息列表
     * @param semesterId          学期
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public R batchImportExcelData(List<AddUserTemplate> addUserTemplateList, Integer semesterId, Integer agencyId) {
        if (addUserTemplateList.isEmpty()) {
            return R.Failed("文件内容为空！");
        }
        //批量新增岗位
        List<String> positionNames = addUserTemplateList.stream().map(AddUserTemplate::getPostName).distinct().collect(Collectors.toList());
        for (String positionName : positionNames) {
            Position position = positionService.getPositionInfoByName(positionName);
            if (ObjectUtils.isEmpty(position)) {
                position = new Position();
                position.setName(positionName);
                Integer insertPosition = positionMapper.insert(position);
                if (insertPosition == 0) {
                    throw new RuntimeException("插入岗位异常");
                }
            }
        }
        //批量新增班级
        List<String> classNames = addUserTemplateList.stream().map(AddUserTemplate::getClassInfo).distinct().collect(Collectors.toList());
        for (String className : classNames) {
            Clazz clazz = clazzService.getClazzInfoByName(className);
            if (ObjectUtils.isEmpty(clazz)) {
                clazz = new Clazz();
                clazz.setClassName(className);
                Integer insertClazz = clazzMapper.insert(clazz);
                if (insertClazz == 0) {
                    throw new RuntimeException("插入班级失败！");
                }
            }
        }
        //批量新增项目
        List<String> projectLists = addUserTemplateList.stream().map(AddUserTemplate::getProjectList).distinct().collect(Collectors.toList());
        List<String> projectNames = new ArrayList<>();
        projectLists.stream().forEach(projectList -> {
            Arrays.stream(projectList.split(StringConst.PROJECT_SEPARATOR)).forEach(projectName -> {
                projectNames.add(projectName);
            });
        });
        List<String> projectNameList = projectNames.stream().distinct().collect(Collectors.toList());
        for (String projectName : projectNameList) {
            Project project = projectMapper.selectOne(new LambdaQueryWrapper<Project>().eq(Project::getProjectName, projectName));
            if (ObjectUtils.isEmpty(project)) {
                project = new Project();
                project.setProjectName(projectName);
                Integer insertProject = projectMapper.insert(project);
                if (insertProject == 0) {
                    throw new RuntimeException("插入项目失败！");
                }
            }
        }
        //判断是否已经添加
        Set<String> userAccountInserted = new HashSet<>();
        //批量新增学生
        for (AddUserTemplate addUserTemplate : addUserTemplateList) {
            //根据学号从数据库中查询是否有该学生，如果有，返回该学生用户，如果没有，则新创建一个用户对象
            User student = userService.getUserByUserName(addUserTemplate.getStudentAccount());
            if (ObjectUtils.isEmpty(student)) {
                student = new User();
            }
            student.setUsername(addUserTemplate.getStudentAccount());
            student.setPassword(passwordEncoder.encode(StringConst.DEFAULT_PASSWORD));
            student.setFullName(addUserTemplate.getStudentName());
            student.setEnabled(true);
            student.setAgencyId(agencyId);
            //1、根据岗位名称查询岗位表中的对应岗位ID，如果不存在则插入该岗位
            Position position = positionService.getPositionInfoByName(addUserTemplate.getPostName());
            student.setPositionId(position.getId());
            //2、根据班级名称查询班级表中的对应班级ID，如果不存在则插入该班级
            Clazz clazz = clazzService.getClazzInfoByName(addUserTemplate.getClassInfo());
            student.setClassId(clazz.getId());
            //3、根据教师账号查询用户表中的对应教师，如果不存在则插入该教师 还有关系表
            User nominalTeacher = userMapper.selectOne(new LambdaQueryWrapper<User>().eq(User::getUsername, addUserTemplate.getNominalTeacherAccount()));
            if (ObjectUtils.isEmpty(nominalTeacher)) {
                nominalTeacher = new User();
            }
            nominalTeacher.setUsername(addUserTemplate.getNominalTeacherAccount());
            nominalTeacher.setPassword(passwordEncoder.encode(StringConst.DEFAULT_PASSWORD));
            nominalTeacher.setFullName(addUserTemplate.getNominalTeacherName());
            nominalTeacher.setEnabled(true);
            nominalTeacher.setAgencyId(agencyId);
            if (!userService.saveOrUpdate(nominalTeacher)) {
                throw new RuntimeException("导入教师失败！");
            } else {
                //插入用户角色表
                userRoleService.insertUserRole(nominalTeacher.getId(), StringConst.TEACHER);
            }
            //4、根据实际教师账号查询用户表中的对应教师，如果不存在则插入该教师 还有关系表
            User teacher = null;
            if (!ObjectUtils.isEmpty(addUserTemplate.getTeacherAccount())) {
                teacher = userMapper.selectOne(new LambdaQueryWrapper<User>()
                        .eq(!ObjectUtils.isEmpty(addUserTemplate.getTeacherAccount()), User::getUsername, addUserTemplate.getTeacherAccount()));
                if (ObjectUtils.isEmpty(teacher)) {
                    teacher = new User();
                }
                teacher.setUsername(addUserTemplate.getTeacherAccount());
                teacher.setPassword(passwordEncoder.encode(StringConst.DEFAULT_PASSWORD));
                teacher.setFullName(addUserTemplate.getTeacherName());
                teacher.setEnabled(true);
                teacher.setAgencyId(agencyId);
                if (!userService.saveOrUpdate(teacher)) {
                    throw new RuntimeException("导入实际教师失败！");
                } else {
                    //插入用户角色表
                    userRoleService.insertUserRole(teacher.getId(), StringConst.TEACHER);
                }
            }
            //插入学生
            if (!userService.saveOrUpdate(student)) {
                throw new RuntimeException("导入学生失败！");
            } else {
                //插入用户角色表
                userRoleService.insertUserRole(student.getId(), StringConst.STUDENT);
            }
            //根据学生ID和学期ID查询学生老师关系表中是否已经有该条数据了
            List<StudentTeacher> studentTeacherList = studentTeacherMapper.selectList(new LambdaQueryWrapper<StudentTeacher>()
                    .eq(StudentTeacher::getStudentId, student.getId())
                    .eq(StudentTeacher::getSemesterId, semesterId));
            StudentTeacher studentTeacher = new StudentTeacher();

            if (CollectionUtils.isEmpty(studentTeacherList)) {
                studentTeacher.setStudentId(student.getId());
                studentTeacher.setSemesterId(semesterId);
            } else {
                studentTeacher.setId(studentTeacherList.get(0).getId());
            }
            //插入学生老师关系表
            studentTeacher.setHonoraryTeacherId(nominalTeacher.getId());
            if (!ObjectUtils.isEmpty(teacher)) {
                studentTeacher.setPracticalTeacherId(teacher.getId());
            }
            if (!studentTeacherService.saveOrUpdate(studentTeacher)) {
                throw new RuntimeException("导入学生教师关系表失败！");
            }
            //5、根据项目名称查询项目表中的对应项目ID，如果不存在则插入该项目
            String[] studentProjectNames = addUserTemplate.getProjectList().split("@");
            // 删掉之前用户的项目
            userProjectMapper.delete(new LambdaQueryWrapper<UserProject>()
                    .eq(UserProject::getUserId, student.getId())
                    .eq(UserProject::getSemesterId, semesterId));
            for (String projectName : studentProjectNames) {
                Project project = projectMapper.selectOne(new LambdaQueryWrapper<Project>().eq(Project::getProjectName, projectName));
                //插入学生项目关系
                UserProject userProject = new UserProject();
                userProject.setUserId(student.getId());
                userProject.setProjectId(project.getId());
                userProject.setSemesterId(semesterId);
                Integer insertUserProject = userProjectMapper.insert(userProject);
                if (insertUserProject == 0) {
                    throw new RuntimeException("插入学生项目关系失败！");
                }
            }
        }
        return R.Success(addUserTemplateList);
    }
}
